Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/面试/面经

11 B站-一面

2 分钟阅读 · Note

目录树 578 篇

          • 0 面试技巧&HR面⬇️
          • 1磐松资产-前端实习-一面
          • 2字节跳动-豆包前端实习-全部
          • 3百度-前端实习面试-一面
          • 5光庭-前端实习-一面
          • 6懂车帝-前端实习-一面
          • 7字节-抖音团购-全部
          • 8腾讯-前端-全部
          • 9字节&美团-笔试
          • 10 美团-一面
          • 11 B站-一面
          • 12 腾讯-一面-企业微信团队
          • 13 腾讯-一面-腾讯金融科技
          • 14 腾讯-二面-腾讯金融科技
          • 15 美团-一面-核心本地商业
          • 16 斑马智行-全部
          • 17 字节-一面-飞书
          • 18 美团-二面-核心本地商业
          • 19 心影随形-全部
          • 20 thunderbit-全部
          • 21 converge ai-全部
          • 22 字节-国际化广告创意与品牌
        • 可投递企业
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗0 面试技巧&HR面⬇️同一路径↗10 美团-一面同一路径↗12 腾讯-一面-企业微信团队同一路径↗13 腾讯-一面-腾讯金融科技同一路径↗14 腾讯-二面-腾讯金融科技同一路径↗15 美团-一面-核心本地商业同一路径
  • 11 B站-一面

11 B站-一面

> Last Format Time:6/12/2026 21:03:57

代码

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 1000)
})
const promise2 = promise1.then((resolve) => {
    console.log(resolve)
})

console.log('promise1', promise1)
console.log('promise2', promise2)

setTimeout(() => {
    console.log('promise1', promise1)
    console.log('promise2', promise2)
}, 2000)

// 错误
// promise1 promise2 Promise<> Promise<> promise1 promise2 error!!! 'success'

// 正确输出
// promise1 Promise { <pending> }
// promise2 Promise { <pending> }
// success
// promise1 Promise { 'success' }
// promise2 Promise { undefined }
  • Promise 状态不可逆:一旦从 pending 变成 fulfilled 或 rejected,状态就永久锁定了。
  • .then() 会返回新 Promise:promise2 并不是 promise1,它的状态和返回值取决于 .then() 回调里的执行情况。
  • 没有 return 等于返回 undefined:.then() 的回调里如果不返回任何值,链式调用下一个 Promise 接收到的值就是 undefined。

这两个问题都是前端面试和实际开发中非常经典的异步编程与性能优化场景。下面为你分别提供清晰的实现方案:


用 Promise 实现图片的懒加载

实现懒加载的核心思路是:

  1. 使用 IntersectionObserver API 监听图片是否进入视口。
  2. 将图片的真实地址放在 data-src 属性中,避免页面加载时直接请求图片。
  3. 当图片进入视口时,通过 Promise 封装图片加载过程,加载成功后将 data-src 赋值给 src。

以下是完整的代码实现:

<!-- HTML 结构:真实图片地址放在 data-src 中 -->
<img class="lazy-img" data-src="https://example.com/image1.jpg" alt="懒加载图片1" style="height: 300px; background: #f0f0f0;">
<img class="lazy-img" data-src="https://example.com/image2.jpg" alt="懒加载图片2" style="height: 300px; background: #f0f0f0;">

<script>
// 1. 用 Promise 封装图片加载过程
function preloadImage(src) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = () => reject(new Error(`图片加载失败: ${src}`));
    img.src = src;
  });
}

// 2. 创建 IntersectionObserver 实例
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      const realSrc = img.dataset.src;

      // 使用 Promise 加载图片
      preloadImage(realSrc)
        .then(() => {
          img.src = realSrc; // 加载成功后替换 src
          img.classList.add('loaded');
          observer.unobserve(img); // 加载完成停止观察
        })
        .catch((err) => {
          console.error(err);
          observer.unobserve(img); // 失败也要停止观察,避免死循环
        });
    }
  });
}, {
  rootMargin: '100px 0px' // 提前 100px 开始加载
});

// 3. 开始观察所有带有 lazy-img 类的图片
document.querySelectorAll('.lazy-img').forEach(img => {
  observer.observe(img);
});
</script>

用 Promise 实现红绿灯交替(红3s, 黄1s, 绿3s)

实现红绿灯无限循环的关键在于:利用 Promise 配合 setTimeout 控制时间,并通过递归(或 .then 链末尾再次调用自身)来实现无限循环。

// 封装一个通用的亮灯函数,返回一个 Promise
function lightUp(color, duration) {
  return new Promise((resolve) => {
    console.log(`${color}灯亮起`);
    setTimeout(() => {
      resolve(); // 指定时间后结束当前 Promise
    }, duration);
  });
}

// 定义红绿灯循环函数
function trafficLight() {
  // 按照 红 -> 黄 -> 绿 的顺序链式调用
  lightUp('红', 3000)
    .then(() => lightUp('黄', 1000))
    .then(() => lightUp('绿', 3000))
    .then(() => {
      // 一轮结束后,再次调用自身,实现无限循环
      trafficLight(); 
    });
}

// 启动红绿灯
trafficLight();

实现原理解析

  • lightUp 函数接收颜色和持续时间,返回一个在指定时间后 resolve 的 Promise。
  • trafficLight 函数通过 .then() 将红、黄、绿三个异步操作串联起来,保证了严格的执行顺序。
  • 在绿灯的 Promise 完成后,再次调用 trafficLight(),从而形成一个完美的异步闭环。